#!/usr/bin/env node

// 小车功能测试脚本
const WebSocket = require('ws');
const { execSync } = require('child_process');

console.log("🚀 开始小车功能测试...");

// 获取本机IP地址
function getLocalIP() {
  const interfaces = require('os').networkInterfaces();
  for (let devName in interfaces) {
    const iface = interfaces[devName];
    for (let i = 0; i < iface.length; i++) {
      const alias = iface[i];
      if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
        return alias.address;
      }
    }
  }
  return 'localhost';
}

// 测试GPIO引脚
function testGPIO() {
  console.log("\n🔧 测试GPIO引脚...");
  try {
    // 测试引脚12 (舵机)
    execSync('gpio -g mode 12 out');
    execSync('gpio -g write 12 1');
    console.log("  ✅ GPIO 12 (舵机) 高电平输出正常");
    execSync('gpio -g write 12 0');
    
    // 测试引脚13 (电调)
    execSync('gpio -g mode 13 out');
    execSync('gpio -g write 13 1');
    console.log("  ✅ GPIO 13 (电调) 高电平输出正常");
    execSync('gpio -g write 13 0');
    
    console.log("  ✅ GPIO引脚测试通过");
    return true;
  } catch (error) {
    console.error("  ❌ GPIO测试失败:", error.message);
    return false;
  }
}

// 测试WebSocket连接
async function testWebSocket() {
  console.log("\n🔌 测试WebSocket连接...");
  const localIP = getLocalIP();
  const wsUrl = `ws://${localIP}:8080/control`;
  
  console.log(`  连接到: ${wsUrl}`);
  
  return new Promise((resolve) => {
    const ws = new WebSocket(wsUrl);
    
    ws.on('open', function open() {
      console.log("  ✅ WebSocket连接成功");
      ws.close();
      resolve(true);
    });
    
    ws.on('error', function error(err) {
      console.error("  ❌ WebSocket连接失败:", err.message);
      resolve(false);
    });
    
    // 5秒超时
    setTimeout(() => {
      console.error("  ❌ WebSocket连接超时");
      if (ws.readyState === WebSocket.CONNECTING) {
        ws.terminate();
      }
      resolve(false);
    }, 5000);
  });
}

// 测试PWM信号
async function testPWMSignals() {
  console.log("\n📡 测试PWM信号...");
  
  try {
    // 初始化引脚
    execSync('gpio -g mode 12 out');
    execSync('gpio -g mode 13 out');
    
    // 发送中性信号 (1.5ms)
    console.log("  发送中性信号...");
    sendPWM(12, 1.5, 1000); // 舵机中性
    sendPWM(13, 1.5, 1000); // 电调中性
    
    // 发送前进信号
    console.log("  发送前进信号...");
    sendPWM(13, 1.7, 1000); // 电调前进
    
    // 发送转向信号
    console.log("  发送右转信号...");
    sendPWM(12, 1.8, 1000); // 舵机右转
    
    console.log("  ✅ PWM信号测试完成");
    return true;
  } catch (error) {
    console.error("  ❌ PWM信号测试失败:", error.message);
    return false;
  }
}

// 发送PWM信号的辅助函数
function sendPWM(pin, dutyCycleMs, durationMs) {
  const periodMs = 20; // 50Hz = 20ms周期
  const highTimeMs = dutyCycleMs;
  const lowTimeMs = periodMs - dutyCycleMs;
  
  const cycles = Math.floor(durationMs / periodMs);
  
  for (let i = 0; i < cycles; i++) {
    execSync(`gpio -g write ${pin} 1`);
    busyWait(highTimeMs * 1000); // 转换为微秒
    execSync(`gpio -g write ${pin} 0`);
    busyWait(lowTimeMs * 1000); // 转换为微秒
  }
}

// 简单的忙等待函数（微秒）
function busyWait(microseconds) {
  const start = process.hrtime.bigint();
  const waitTime = BigInt(microseconds) * BigInt(1000); // 转换为纳秒
  
  while (process.hrtime.bigint() - start < waitTime) {
    // 忙等待
  }
}

async function main() {
  console.log("🚗 小车功能综合测试");
  
  // 测试GPIO
  const gpioSuccess = testGPIO();
  
  // 测试WebSocket
  const wsSuccess = await testWebSocket();
  
  // 测试PWM信号
  const pwmSuccess = await testPWMSignals();
  
  console.log("\n📋 测试结果总结:");
  console.log(`  GPIO测试: ${gpioSuccess ? '✅ 通过' : '❌ 失败'}`);
  console.log(`  WebSocket测试: ${wsSuccess ? '✅ 通过' : '❌ 失败'}`);
  console.log(`  PWM信号测试: ${pwmSuccess ? '✅ 通过' : '❌ 失败'}`);
  
  if (gpioSuccess && wsSuccess && pwmSuccess) {
    console.log("\n🎉 所有测试通过！小车应该可以正常工作了。");
    console.log("\n📱 请在浏览器中访问以下地址来控制小车:");
    const localIP = getLocalIP();
    console.log(`   http://${localIP}:8080`);
  } else {
    console.log("\n⚠️  部分测试失败，请检查以下可能的问题:");
    if (!gpioSuccess) {
      console.log("   - GPIO引脚配置问题");
    }
    if (!wsSuccess) {
      console.log("   - 网络连接或WebSocket服务问题");
    }
    if (!pwmSuccess) {
      console.log("   - PWM信号生成问题");
    }
    console.log("\n🔧 建议检查:");
    console.log("   1. 硬件连接是否正确");
    console.log("   2. 电源供应是否充足");
    console.log("   3. 电调是否需要校准");
    console.log("   4. 舵机是否正常工作");
  }
}

main();